/*
 * Created by Jaren at 2021/10/28 17:43
 */
import 'package:ble_plugin/ble_device_filter.dart';
import 'package:ble_plugin/ble_plugin.dart';
import 'package:ble_plugin/ble_uuid.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';
import 'package:inmotion_protocol/inmotion_protocol.dart';
import 'package:inmotion_protocol_example/module/base/base.dart';
import 'package:inmotion_protocol_example/module/global/global.dart';
import 'package:inmotion_protocol_example/module/operation/operation_controller.dart';
import 'package:inmotion_protocol_example/module/operation/operation_view.dart';
import 'package:inmotion_protocol_example/module/widget/prompt.dart';
import 'package:inmotion_protocol/util/log.dart';

class LxSearchController extends BaseController {
  static final _bleUuid1 = BleUuid(
      "0000ffe5-0000-1000-8000-00805f9b34fb",
      "0000ffe9-0000-1000-8000-00805f9b34fb",
      "0000ffe0-0000-1000-8000-00805f9b34fb",
      "0000ffe4-0000-1000-8000-00805f9b34fb");
  static final _bleUuid2 = BleUuid(
      "6e400001-b5a3-f393-e0a9-e50e24dcca9e",
      "6e400002-b5a3-f393-e0a9-e50e24dcca9e",
      "6e400001-b5a3-f393-e0a9-e50e24dcca9e",
      "6e400003-b5a3-f393-e0a9-e50e24dcca9e");

  // 扫描到的设备列表
  final devices = <BluetoothDevice>[].obs;

  // 当前系统蓝牙状态
  Rx<BluetoothState> btState = BluetoothState.unknown.obs;

  final BleManager _bleManager = BleManager();

  RxBool isScan = false.obs;
  RxBool searching = false.obs;
  RxBool connecting = false.obs;

  @override
  init() {
    _bleManager.getBtState().then((value) => btState.value = value);
    _bleManager.addSupportedBleServices([
      _bleUuid1,
      _bleUuid2, /*_bleUuid3*/
    ]);
    _bleManager.onStateChangedCallback = _onBtDeviceStateChangedCallback;
  }

  Future<bool> scan() async {
    if (searching.value) stopScanning();
    await Future.delayed(const Duration(seconds: 1));
    print('Start scan');
    _bleManager.scan().listen((scanResult) {
      if (scanResult.device.name.isNotEmpty) {
        devices.add(scanResult.device);
      }
    }, onDone: () => searching.value = false);

    searching.value = true;
    return true;
  }

  bool stopScanning() {

    print('Stop scan');
    _bleManager.stopScan();
    searching.value = false;
    return true;
  }

  connect({BluetoothDevice? device, String? identify, String? name}) {
    if (searching.value) stopScanning();
    // _bleManager.connect(device: device, name: name, timeout: const Duration(seconds: 10));
    _bleManager.connect(
        device: device,
        // id: device!.id.id,
        // name: name,
        timeout: const Duration(seconds: 10),
        timeoutCallback: () {
          connecting.value = false;
          isLoading.value = false;
          Prompt.showToast("Fail", 'Connect timeout');

          print('Connect timeout');
        });
    isLoading.value = true;
  }

  _onBtDeviceStateChangedCallback(BluetoothDevice device, state,
      {String? flag}) async {
    print(state);

    var fwUpdating = Global.getInstance().get("fw_updating", false);
    var connectedCallback = Global.getInstance().get("bt_state_change_handler");

    switch (state) {
      case BluetoothDeviceState.disconnected:
        if (fwUpdating) {
          if (connectedCallback != null)
            connectedCallback(false, device.id.id, device.name);
          return;
        }
        connecting.value = false;
        isLoading.value = false;
        Prompt.showToast("Fail", 'Device has disconnected');

        print('Device has disconnected');
        break;
      case BluetoothDeviceState.connecting:
        print('Device is connecting');
        break;
      case BluetoothDeviceState.connected:
        print('Device has connected');
        if (fwUpdating) {
          await _bleManager.requestMtu(220, device: device);
          BleManager().config(InMotionProtocol.getDeviceConfig(device.name));
          if (connectedCallback != null)
            connectedCallback(true, device.id.id, device.name);
          return;
        }
        connecting.value = true;
        isLoading.value = false;
        Prompt.showToast("Success", 'Device has connected');
        _bleManager.requestMtu(220, device: device);
        Get.to(OperationPage(), binding: BindingsBuilder(() {
          Get.put(OperationController());
        }));
        break;
      case BluetoothDeviceState.disconnecting:
        print('Device is disconnecting');
        break;
    }
  }
}
